package com.puzzlebazar.client.squaregrid.view;

import java.util.Vector;

import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Widget;
import com.puzzlebazar.client.util.Recti;
import com.puzzlebazar.client.util.Vec2i;

public class GridDisplay extends CompositeView {

	private Vector<Widget> hLines = new Vector<Widget>();
    private Vector<Widget> vLines = new Vector<Widget>();
    private AbsolutePanel decorationPanel = new AbsolutePanel();

    public GridDisplay() {
    	super();
    	initWidget( decorationPanel );
    }
    
	protected void notifyCellChanged() {
		SGView view = getView();
		try {
			updateLines( vLines, view.getGridSize().x + 1, true );
			updateLines( hLines, view.getGridSize().y + 1, false );
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	/**
	 * @return True if there are enough widgets so that they can only be moved around and not recreated
	 */
	private boolean canContentBeUpdated( boolean vertical ) {
		SGView view = getView();
		if( vertical )
			return view.getGridSize().x+1 == vLines.size();
		else
			return view.getGridSize().y+1 == hLines.size();
	}

	/**
	 * Updates or create an array of lines running horizontally or vertically inside a rectangular area
	 * Uses the view pixelSize as the size for the rectangular area
	 * 	
	 * @param list          A vector in which are stored the lines 
	 * @param nbLines       The number of lines to update
	 * @param vertical      true for vertical lines, false for horizontal
	 * @throws Exception 
	 */
	private void updateLines( Vector<Widget> list, int nbLines, boolean vertical ) throws Exception {
		SGView view = getView();
		boolean create = !canContentBeUpdated(vertical);
		
		if ( create ) {
			deleteLines(list);
		}
		Vec2i pixelPos;
		Vec2i vertexLoc = new Vec2i(0,0);
		for( int i = 0; i < nbLines; ++i ) {
			if ( vertical )
				vertexLoc.x = i;
			else
				vertexLoc.y = i;

			pixelPos = view.getVertexPosition(vertexLoc);
			
			Widget line;
			if( !create )
				line = list.get( i );
			else {
				line = new AbsolutePanel();
				line.setStylePrimaryName( "gridLine" );
			}
			Recti innerRect = view.getInnerRect();
			line.setPixelSize( vertical ? 1 : innerRect.w, vertical ? innerRect.h : 1 );
			if ( create ) {
				decorationPanel.add( line, pixelPos.x, pixelPos.y);
				list.add(line);
			}
			else
				decorationPanel.setWidgetPosition( line, pixelPos.x, pixelPos.y );
		}
	}

	/**
	 * Delete every images from the list and remove them from the panel widget
	 * 
	 * @param list List of images to remove 
	 * @throws Exception 
	 */
	private void deleteLines(Vector<Widget> list) throws Exception {
		for (Widget image : list) {
			decorationPanel.remove( image );
		}
		list.clear();
	}

}
